package com.niiwoo.civet.trade.service.local.loantest;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.rdb.sharding.api.HintManager;
import com.niiwoo.civet.account.dto.response.AccountBaseResponse;
import com.niiwoo.civet.account.service.AccountDubboService;
import com.niiwoo.civet.base.enums.DeadlineUnitEnum;
import com.niiwoo.civet.trade.dao.entity.*;
import com.niiwoo.civet.trade.dao.mapper.ProjectMapperExt;
import com.niiwoo.civet.trade.dao.mapper.ProjectRateMapperExt;
import com.niiwoo.civet.trade.dao.mapper.RateConfigPercentMapperExt;
import com.niiwoo.civet.trade.dto.common.ProjectDynamicDTO;
import com.niiwoo.civet.trade.dto.request.loan.PushProjectRequestDTO;
import com.niiwoo.civet.trade.enums.*;
import com.niiwoo.civet.trade.service.local.common.ProjectCommonService;
import com.niiwoo.civet.trade.service.local.configure.TradeConfigLocalService;
import com.niiwoo.civet.trade.service.local.loan.SpeedLoanRateConfigService;
import com.niiwoo.civet.trade.service.local.loan.SpeedLoanService;
import com.niiwoo.civet.trade.service.local.project.ProjectLocalService;
import com.niiwoo.civet.user.service.UserAuthorizationInfoDubboService;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.civet.user.service.UserIdentityDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.lanmao.component.LanMaoDirectService;
import com.niiwoo.tripod.lanmao.component.LanMaoSequence;
import com.niiwoo.tripod.lanmao.enums.ProjectTypeEnum;
import com.niiwoo.tripod.lanmao.enums.ResponseCodeEnum;
import com.niiwoo.tripod.lanmao.enums.ResponseStatusEnum;
import com.niiwoo.tripod.lanmao.enums.UserRoleEnum;
import com.niiwoo.tripod.lanmao.request.EstablishProjectRequest;
import com.niiwoo.tripod.lanmao.request.QueryProjectInformationRequest;
import com.niiwoo.tripod.lanmao.response.LanMaoResponse;
import com.niiwoo.tripod.lanmao.response.QueryProjectInformationResponse;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * @Description:
 * @Author:LiJian
 * @Date:2017/11/8
 */
@Slf4j
@Service
@Deprecated
public class SpeedLoanTestService {
    static final int PRECISION_TWO = 2;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private ProjectMapperExt projectMapper;
    @Autowired
    PrivacyMasks privacyMasks;
    @Autowired
    private TradeConfigLocalService tradeConfigService;
    @Autowired
    private SpeedLoanRateConfigService speedLoanRateConfigService;
    @Autowired
    private ProjectRateMapperExt projectRateMapper;
    @Autowired
    private RateConfigPercentMapperExt rateConfigPercentMapper;
    @Autowired
    private ProjectLocalService projectLocalService;
    @Autowired
    private SpeedLoanService loanLocalService;
    @Autowired
    private LanMaoSequence lanMaoSequence;

    @Reference(version = "1.0.0")
    private UserIdentityDubboService userIdentityDubboService;
    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private UserAuthorizationInfoDubboService userAuthorizationInfoDubboService;
    @Autowired
    private ProjectCommonService projectCommonService;
    @Autowired
    private LanMaoDirectService lanMaoDirectService;

    @Reference(version = "1.0.0")
    AccountDubboService accountDubboService;

    public void speedLoanApplyTest(LoanApplyTestRequestDTO loanApplyTestRequestDTO) {
        Long projectId = snowflakeIdWorker.nextId();
        getSelfProxy().loanProjectRelateInfoCreat(this.initProject(loanApplyTestRequestDTO, projectId));

        PushProjectRequestDTO pushProjectRequestDTO = new PushProjectRequestDTO();
        pushProjectRequestDTO.setProjectId(projectId);
        pushProjectRequestDTO.setPushFromEnum(PushProjectRequestDTO.PushFromEnum.HAND_AUDIT);
        pushProject(pushProjectRequestDTO);
    }

    public Project initProject(LoanApplyTestRequestDTO loanApplyTestRequestDTO, Long projectId) {
        Project project = new Project();
        String userId = loanApplyTestRequestDTO.getUserId();

        Date now = new Date();

        project.setProjectId(projectId);
        BigDecimal loanAmount = loanApplyTestRequestDTO.getLoanAmount();

        project.setLoanTimes(1);  //借款成功次数
        project.setBorrowUserId(userId); //借款用户
        project.setBorrowUserName("test"); //借款人姓名
        project.setBorrowMobile(this.ecryptString("13691629214")); //借款人手机号，加密
        project.setBorrowIdCard(this.ecryptString("110101199410018077")); //身份证号，加密
        project.setTitle("借款用于" + loanApplyTestRequestDTO.getLoanTitle()); //项目标题
        project.setContractAmount(loanAmount); //合同金额,也即标的金额
        project.setHandAmount(loanAmount); //到手金额

        project.setBorrowNickName("test"); //昵称
        project.setBorrowHeadImage("https://image.niiwoo.com:5003/api/20160727/img/20160727164827631220.jpg"); //头像
        project.setBorrowGender((byte) 1); //性别
        project.setBorrowNiiwooScore(300); //你我分

        project.setStatus(ProjectSubStatusEnum.CHECKING_INIT.getParentStatusEnum().getStatus()); //项目状态（1待发布、2审核中、3筹款中、4还款中、5已结清、6流标）
        project.setSubStatus(ProjectSubStatusEnum.CHECKING_INIT.getSubStatus()); //子状态，如100，200
//        project.setChannelCode("app"); //投放渠道CODE(APP为默认渠道其它：参考tnw_userDrainageChannel表channelCode字段)
        project.setType((byte) 1);  //类型(默认1:个人极速借2:机构极速借)
        project.setFromSource(ProjectFromSourceEnum.APP.getType()); //标的来源（1、APP，2、H5活动，3、H5极速借,4、融360）
        project.setZhimaScore(700); //芝麻分(冗余)
        project.setContactsBackflowStatus(ContactsBackflowStatusEnum.SUCCESS.getValue()); //通讯录回流状态(0、未回流1、已回流2、回流失败)
        project.setCreditType((byte) 1); //授信额度类型(1:社保,2:芝麻,3:学历)
        project.setLoanType(ProjectCreditTypeEnum.typeOf(project.getCreditType()).getLoanTypeEnum().getValue());
        project.setLongitude("113.9570606891296"); //经度
        project.setLatitude("22.56018585190962"); //纬度
        project.setLoanProvince("广东"); //借款省
        project.setLoanCity("深圳市");  //借款市
        project.setLoanArea("南山区");  //借款区
        project.setAutoAuditResult((byte) 1);
        project.setSubmitTime(now);  //借款人提交到后台审核时间
        project.setCreateTime(now);  //添加时间
        project.setUpdateTime(now);  //更新时间

        String penaltyRateStr = tradeConfigService.selectTradeConfigByEmun(TradeConfigEnum.OVERDUEFEERATE);
        project.setPenaltyRate(new BigDecimal(penaltyRateStr)); //预期罚息率


        //设置平台管理费、担保费等
        Integer deadline = loanApplyTestRequestDTO.getDeadline();
        ProjectRateConfig projectRateConfig = speedLoanRateConfigService.getRateConfigByDeadline(deadline);
        if (projectRateConfig == null) {
            throw new BizException("借款期限配置错误");
        }
        BigDecimal platformManageFeeRate = projectRateConfig.getPlatformManageFeeRate();
        BigDecimal guaranteeServiceFeeRate = projectRateConfig.getGuaranteeServiceFeeRate();

        project.setBorrowRate(projectRateConfig.getBorrowInterestRate()); //借款利率
        project.setManageRate(platformManageFeeRate); //平台管理费率
        project.setGuaranteeRate(guaranteeServiceFeeRate); //担保费率
        project.setRepaymentType(projectRateConfig.getRepaymentMode());//还款方式1、到期还本付息，2、等额本息
        project.setDeadline(deadline); //期数
        project.setDeadlineUnit(DeadlineUnitEnum.BY_MONTH.getDeadlineUnit()); //期数单位(1:月，2:天)

        BigDecimal platformManageFee = loanAmount.multiply(platformManageFeeRate).setScale(PRECISION_TWO, BigDecimal.ROUND_HALF_UP);
        BigDecimal guaranteeServiceFee = loanAmount.multiply(guaranteeServiceFeeRate).setScale(PRECISION_TWO, BigDecimal.ROUND_HALF_UP);
        //设置平台管理费和担保服务费用
        project.setManageFee(platformManageFee);
        project.setGuaranteeFee(guaranteeServiceFee);

        return project;
    }

    private String ecryptString(String str) {
        return Optional.ofNullable(str).map(s -> privacyMasks.encryptPrivacy(str)).orElse(null);
    }

    @Transactional(rollbackFor = Exception.class)
    public void loanProjectRelateInfoCreat(Project project) {
        log.info("loanProjectRelateInfoCreat.project={}", JSON.toJSONString(project));
        String userId = project.getBorrowUserId();
        Long projectId = project.getProjectId();
        projectMapper.insertSelective(project);

        //插入标的费率数据
        projectRateCreat(userId, projectId, project.getDeadline());

        ProjectDynamicDTO projectDynamicDTO = new ProjectDynamicDTO();
        projectDynamicDTO.setUserId(userId);
        projectDynamicDTO.setProjectId(projectId);
        projectDynamicDTO.setTradeTypeEnum(ProjectDynamicDTO.TradeTypeEnum.REPAYMENT);
        projectDynamicDTO.setProjectDynamicEnum(ProjectDynamicEnum.APPLY_SUBMIT_SUCCESS);
        projectLocalService.addProjectDynamicRecord(projectDynamicDTO);
    }

    private void projectRateCreat(String userId, Long projectId, Integer deadline) {
        //先删除，后插入
        projectRateMapper.deleteByUserIdProjectId(userId, projectId);
        ProjectRateConfig projectRateConfig = speedLoanRateConfigService.getRateConfigByDeadline(deadline);
        List<RateConfigPercent> rateConfigPercentList = rateConfigPercentMapper.queryConfigPercentByRateConfigId(projectRateConfig.getId());
        for (RateConfigPercent rateConfigPercent : rateConfigPercentList) {
            ProjectRate projectRate = new ProjectRate();
            BeanUtils.copyProperties(rateConfigPercent, projectRate);
            projectRate.setId(snowflakeIdWorker.nextId());
            projectRate.setBorrowUserId(userId);
            projectRate.setProjectId(projectId);
            projectRate.setCreateTime(new Date());
            projectRateMapper.insertSelective(projectRate);
        }
    }

    public void pushProject(PushProjectRequestDTO pushProjectRequestDTO) {
//        HintManager hintManager = HintManager.getInstance();
//        hintManager.setMasterRouteOnly();
//
//        Project project = projectCommonService.queryProjectBasicInfo(pushProjectRequestDTO.getProjectId());
//        if (project == null) {
//            throw new BizException("TRD20001");
//        }
//
//        AccountBaseResponse accountBaseResponse = accountDubboService.getNiiwooAccount(project.getBorrowUserId(), UserRoleEnum.BORROWERS);
//        if (accountBaseResponse == null) {
//            throw new BizException("TRD40002");
//        }
//
//        try {
//            QueryProjectInformationRequest queryProjectInformationRequest = new QueryProjectInformationRequest();
//            queryProjectInformationRequest.setProjectNo(String.valueOf(pushProjectRequestDTO.getProjectId()));
//            log.info("推标,标的ID={},开始调用查询存管标的信息接口,请求参数={}", pushProjectRequestDTO.getProjectId(), JSON.toJSONString(queryProjectInformationRequest));
//            CompletableFuture<QueryProjectInformationResponse> completableFuture4QueryProejct = lanMaoDirectService.queryProjectInformation(queryProjectInformationRequest);
//            QueryProjectInformationResponse queryProjectInformationResponse = completableFuture4QueryProejct.get();
//            log.info("推标,标的ID={},结束调用查询存管标的信息接口,响应结果={}", pushProjectRequestDTO.getProjectId(), JSON.toJSONString(queryProjectInformationResponse));
//            //1.成功;
//            if (ResponseCodeEnum.SUCCESS.getValue().equals(queryProjectInformationResponse.getCode())
//                    && ResponseStatusEnum.SUCCESS.getValue().equals(queryProjectInformationResponse.getStatus())) {
//                if (queryProjectInformationResponse.getProjectStatus() != null) {
//                    //若存管已上标,且标的状态为COLLECTING(募集中),则直接进行本地业务上标操作;
//                    if (queryProjectInformationResponse.getProjectStatus().equals(com.niiwoo.tripod.lanmao.enums.ProjectStatusEnum.COLLECTING)) {
//                        pushProjectSuccess(pushProjectRequestDTO, project);
//                    }
//                    //若存管标的状态不为COLLECTING(募集中)状态,则证明此时流程已经出问题,直接进行错误日志记录;
//                    else {
//                        log.error("推标,标的ID={},发生异常,原因是上标时存管标的状态不为募集中状态,存管标的信息={}", pushProjectRequestDTO.getProjectId(), JSON.toJSONString(queryProjectInformationResponse));
//                        throw new BizException("TRD40004");
//                    }
//                }
//            }
//            //若查询存管标的信息失败,则不做操作,且记录失败情况;
//            else {
//                //若存管无此标的信息,则进行存管与业务上标操作;
//                EstablishProjectRequest establishProjectRequest = transProject2EstablishProjectRequest(project);
//                establishProjectRequest.setPlatformUserNo(accountBaseResponse.getAccountNo());
//                log.info("推标,标的ID={},开始调用存管上标接口,请求参数={}", pushProjectRequestDTO.getProjectId(), establishProjectRequest);
//                CompletableFuture<LanMaoResponse> completableFuture = lanMaoDirectService.establishProject(establishProjectRequest);
//                LanMaoResponse response = completableFuture.get();
//                log.info("推标,标的ID={},开始调用存管上标接口,响应结果={}", pushProjectRequestDTO.getProjectId(), response);
//                //1.成功;
//                if (ResponseCodeEnum.SUCCESS.getValue().equals(response.getCode())
//                        && ResponseStatusEnum.SUCCESS.getValue().equals(response.getStatus())) {
//                    pushProjectSuccess(pushProjectRequestDTO, project);
//                }
//                //2.失败;
//                else {
//                    log.error("推标,标的ID={},上标失败,原因={}", pushProjectRequestDTO.getProjectId(), JSON.toJSONString(response));
//                    //场景一：补偿机制上标;
//                    if (pushProjectRequestDTO.getProjectPushRecordId() != null) {
//                        loanLocalService.updatePushProjectRecordStatus(pushProjectRequestDTO.getProjectPushRecordId(), (byte) 2, response.getErrorCode(), response.getStatus(), response.getErrorMessage());
//                    }
//                    //场景二：后台人工审核通过上标;
//                    else {
//                        switch (pushProjectRequestDTO.getPushFromEnum()) {
//                            //自动审核
//                            case AUTO_AUDIT:
//                                //录入审核失败记录;
//                                loanLocalService.initProejctPushRecord(pushProjectRequestDTO, response.getCode(), response.getStatus(), response.getErrorMessage());
//
//                                //人工审核
//                            case HAND_AUDIT:
//                                throw new BizException("TRD10014");
//                        }
//                    }
//                }
//            }
//        } catch (Exception e) {
//            log.error("推标,标的ID={},发生系统异常,错误信息={}", pushProjectRequestDTO.getProjectId(), e);
//            throw new RuntimeException(e);
//        }
    }

    private void pushProjectSuccess(PushProjectRequestDTO pushProjectRequestDTO, Project project) {
        project.setPublishTime(new Date());
        ProjectInvesting projectInvesting = new ProjectInvesting();
        projectInvesting.setProjectId(project.getProjectId());
        projectInvesting.setBorrowUserId(project.getBorrowUserId());
        projectInvesting.setBorrowHeadImage(project.getBorrowHeadImage());
        projectInvesting.setBorrowNickName(project.getBorrowNickName());
        projectInvesting.setBorrowGender(project.getBorrowGender());
        projectInvesting.setBorrowNiiwooScore(project.getBorrowNiiwooScore());
        projectInvesting.setLoanTimes(project.getLoanTimes());
        projectInvesting.setTitle(project.getTitle());
        projectInvesting.setContractAmount(project.getContractAmount());
        projectInvesting.setInvestedAmount(project.getInvestedAmount());
        projectInvesting.setBorrowRate(project.getBorrowRate());
        projectInvesting.setDeadline(project.getDeadline());
        projectInvesting.setDeadlineUnit(project.getDeadlineUnit());
        projectInvesting.setType(project.getType());
        projectInvesting.setLongitude(project.getLongitude());
        projectInvesting.setLatitude(project.getLatitude());
        projectInvesting.setLoanCity(project.getLoanCity());
        projectInvesting.setLoanArea(project.getLoanArea());
        Date now = new Date();
        projectInvesting.setPublishTime(now);
        projectInvesting.setRepaymentType(project.getRepaymentType());
        projectInvesting.setChannelCode(project.getChannelCode());
        projectInvesting.setCreateTime(now);
        projectInvesting.setCreditType(project.getCreditType());
        projectInvesting.setBorrowerType(project.getBorrowerType());

        loanLocalService.pushProjectSuccess(project, projectInvesting, pushProjectRequestDTO,getProjectDateTime(project));
    }

    protected Map<String,Date> getProjectDateTime(Project project){
        Map<String,Date> dtMap = new HashMap<>();
        Date startDateTime = new Date();
        String investDeadline = tradeConfigService.selectTradeConfigByEmun(TradeConfigEnum.INVESTDEADLINE); //-- default:TradeConfigEnum.INVESTDEADLINE
        if(StringUtils.isEmpty(investDeadline)){
            log.info("推标,标的ID={},筹款期限未配置.", project.getProjectId());
            throw new RuntimeException("筹款期限未配置.");
        }
        Date endDateTime = org.apache.commons.lang3.time.DateUtils.addDays(startDateTime,Integer.valueOf(investDeadline));
        dtMap.put("startDateTime",startDateTime);
        dtMap.put("endDateTime",endDateTime);
        return dtMap;
    }

    private EstablishProjectRequest transProject2EstablishProjectRequest(Project project) {
        EstablishProjectRequest establishProjectRequest = new EstablishProjectRequest();
        establishProjectRequest.setRequestNo(lanMaoSequence.getRequestNo());
        establishProjectRequest.setProjectNo(String.valueOf(project.getProjectId()));
        establishProjectRequest.setProjectAmount(project.getContractAmount());
        establishProjectRequest.setProjectName(project.getTitle());
        establishProjectRequest.setProjectDescription(project.getTitle());
        establishProjectRequest.setProjectType(ProjectTypeEnum.STANDARDPOWDER);
        establishProjectRequest.setProjectPeriod(project.getDeadlineUnit().equals(DeadlineUnitEnum.BY_DAY.getDeadlineUnit()) ? project.getDeadline() : project.getDeadline() * 30);
        establishProjectRequest.setAnnnualInterestRate(project.getBorrowRate().divide(BigDecimal.valueOf(100)));
        establishProjectRequest.setRepaymentWay(loanLocalService.transRepaymentType2LM(RepaymentTypeEnum.enumOf(project.getRepaymentType())));

        return establishProjectRequest;
    }

    private SpeedLoanTestService getSelfProxy() {
        return (SpeedLoanTestService) AopContext.currentProxy();
    }
}
